#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
练习题22: Python语法糖深度实践

本练习涵盖Python 3.8+引入的现代语法糖和高级语法特性，
包括海象运算符、f-string高级用法、解包操作、模式匹配等。

知识点:
- 海象运算符(:=) - Python 3.8+
- f-string高级格式化 - Python 3.6+
- 解包操作(*args, **kwargs, *iterables)
- 位置参数和关键字参数(/, *)
- 类型注解和泛型
- 模式匹配(match-case) - Python 3.10+
- 数据类(dataclass) - Python 3.7+
- 上下文变量(contextvars) - Python 3.7+
"""

import re
import sys
import time
import math
import json
import asyncio
from typing import List, Dict, Tuple, Optional, Union, Any, TypeVar, Generic
from dataclasses import dataclass, field
from functools import wraps, partial
from collections import defaultdict, Counter
from contextlib import contextmanager
from datetime import datetime, timedelta


def walrus_operator_exercises():
    """
    练习1: 海象运算符(:=)的各种应用场景
    
    海象运算符允许在表达式中赋值，减少重复计算和代码冗余
    """
    print("=== 海象运算符练习 ===")
    
    # 练习1.1: 在while循环中使用海象运算符
    def read_input_until_quit():
        """使用海象运算符简化输入循环"""
        inputs = []
        # TODO: 使用海象运算符重写下面的代码
        # 传统写法:
        # user_input = input("Enter text (quit to exit): ")
        # while user_input != 'quit':
        #     inputs.append(user_input)
        #     user_input = input("Enter text (quit to exit): ")
        
        # 海象运算符写法:
        # while (user_input := input("Enter text (quit to exit): ")) != 'quit':
        #     inputs.append(user_input)
        
        return inputs
    
    # 练习1.2: 在列表推导式中使用海象运算符
    def process_expensive_calculations(numbers: List[int]) -> List[int]:
        """在列表推导式中避免重复计算"""
        def expensive_function(x):
            """模拟耗时计算"""
            time.sleep(0.001)  # 模拟计算时间
            return x ** 2 + x + 1
        
        # TODO: 使用海象运算符优化下面的代码
        # 传统写法(重复计算):
        # result = [expensive_function(x) for x in numbers if expensive_function(x) > 10]
        
        # 海象运算符写法:
        # result = [calc for x in numbers if (calc := expensive_function(x)) > 10]
        
        pass
    
    # 练习1.3: 在条件表达式中使用海象运算符
    def find_pattern_in_text(text: str, pattern: str) -> Optional[str]:
        """在文本中查找模式并返回匹配结果"""
        # TODO: 使用海象运算符简化代码
        # 传统写法:
        # match = re.search(pattern, text)
        # if match:
        #     return match.group()
        # return None
        
        # 海象运算符写法:
        # return match.group() if (match := re.search(pattern, text)) else None
        
        pass
    
    # 练习1.4: 在字典推导式中使用海象运算符
    def create_word_length_dict(words: List[str]) -> Dict[str, int]:
        """创建单词长度字典，只包含长度大于3的单词"""
        # TODO: 使用海象运算符优化
        # 传统写法:
        # return {word: len(word) for word in words if len(word) > 3}
        
        # 海象运算符写法:
        # return {word: length for word in words if (length := len(word)) > 3}
        
        pass
    
    # 演示海象运算符的使用
    print("1. 海象运算符在不同场景的应用:")
    
    # 示例数据
    numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    text = "The quick brown fox jumps over the lazy dog"
    words = ["cat", "dog", "elephant", "ant", "butterfly"]
    
    try:
        # 测试各个函数
        result1 = process_expensive_calculations(numbers)
        result2 = find_pattern_in_text(text, r'\b\w{5}\b')  # 查找5字母单词
        result3 = create_word_length_dict(words)
        
        print(f"处理结果: {result1}")
        print(f"模式匹配: {result2}")
        print(f"单词长度字典: {result3}")
    except Exception as e:
        print(f"海象运算符练习出错: {e}")


def advanced_fstring_exercises():
    """
    练习2: f-string高级格式化技巧
    
    f-string不仅支持基本的变量插值，还支持复杂的格式化选项
    """
    print("\n=== f-string高级格式化练习 ===")
    
    # 练习2.1: 数字格式化
    def format_numbers():
        """演示各种数字格式化"""
        pi = math.pi
        large_number = 1234567.89
        percentage = 0.1234
        
        # TODO: 使用f-string实现以下格式化
        # 1. π保留3位小数
        # 2. 大数字添加千位分隔符
        # 3. 百分比格式
        # 4. 科学计数法
        # 5. 二进制、八进制、十六进制
        
        formatted_pi = f"{pi:.3f}"  # 示例
        # TODO: 完成其他格式化
        
        return {
            'pi': formatted_pi,
            # 'large_number': ...,
            # 'percentage': ...,
            # 'scientific': ...,
            # 'binary': ...,
            # 'octal': ...,
            # 'hex': ...
        }
    
    # 练习2.2: 日期时间格式化
    def format_datetime():
        """演示日期时间格式化"""
        now = datetime.now()
        
        # TODO: 使用f-string格式化日期时间
        # 1. ISO格式
        # 2. 中文格式
        # 3. 自定义格式
        
        iso_format = f"{now:%Y-%m-%d %H:%M:%S}"  # 示例
        # TODO: 完成其他格式化
        
        return {
            'iso': iso_format,
            # 'chinese': ...,
            # 'custom': ...
        }
    
    # 练习2.3: 对齐和填充
    def format_alignment():
        """演示文本对齐和填充"""
        name = "Python"
        value = 42
        
        # TODO: 使用f-string实现对齐和填充
        # 1. 左对齐、右对齐、居中
        # 2. 零填充
        # 3. 自定义填充字符
        
        left_align = f"{name:<10}"  # 示例
        # TODO: 完成其他对齐方式
        
        return {
            'left': left_align,
            # 'right': ...,
            # 'center': ...,
            # 'zero_pad': ...,
            # 'custom_pad': ...
        }
    
    # 练习2.4: 表达式和函数调用
    def format_expressions():
        """演示在f-string中使用表达式和函数调用"""
        numbers = [1, 2, 3, 4, 5]
        person = {'name': 'Alice', 'age': 30}
        
        # TODO: 在f-string中使用表达式
        # 1. 数学运算
        # 2. 函数调用
        # 3. 列表推导式
        # 4. 字典访问
        # 5. 条件表达式
        
        math_expr = f"2 + 3 = {2 + 3}"  # 示例
        # TODO: 完成其他表达式
        
        return {
            'math': math_expr,
            # 'function': ...,
            # 'comprehension': ...,
            # 'dict_access': ...,
            # 'conditional': ...
        }
    
    # 练习2.5: 调试格式化
    def format_debugging():
        """演示f-string的调试功能(Python 3.8+)"""
        x = 10
        y = 20
        
        # TODO: 使用f-string的调试格式
        # Python 3.8+支持 {variable=} 语法
        
        if sys.version_info >= (3, 8):
            debug_output = f"{x=}, {y=}, {x+y=}"  # 示例
        else:
            debug_output = f"x={x}, y={y}, x+y={x+y}"
        
        return debug_output
    
    # 演示f-string高级用法
    print("2. f-string高级格式化:")
    
    try:
        numbers_result = format_numbers()
        datetime_result = format_datetime()
        alignment_result = format_alignment()
        expressions_result = format_expressions()
        debug_result = format_debugging()
        
        print(f"数字格式化: {numbers_result}")
        print(f"日期时间格式化: {datetime_result}")
        print(f"对齐格式化: {alignment_result}")
        print(f"表达式格式化: {expressions_result}")
        print(f"调试格式化: {debug_result}")
    except Exception as e:
        print(f"f-string练习出错: {e}")


def unpacking_exercises():
    """
    练习3: 解包操作的高级应用
    
    Python的解包操作不仅限于基本的*args和**kwargs
    """
    print("\n=== 解包操作练习 ===")
    
    # 练习3.1: 多重赋值和解包
    def multiple_assignment():
        """演示多重赋值和解包"""
        # TODO: 实现各种解包操作
        
        # 基本解包
        data = (1, 2, 3, 4, 5)
        # first, *middle, last = data
        
        # 嵌套解包
        nested_data = [(1, 2), (3, 4), (5, 6)]
        # (a, b), (c, d), (e, f) = nested_data
        
        # 字典解包
        person1 = {'name': 'Alice', 'age': 30}
        person2 = {'city': 'New York', 'country': 'USA'}
        # merged = {**person1, **person2}
        
        pass
    
    # 练习3.2: 函数参数解包
    def function_argument_unpacking():
        """演示函数参数解包"""
        def greet(name, age, city="Unknown"):
            return f"Hello {name}, age {age}, from {city}"
        
        # TODO: 使用解包传递参数
        person_tuple = ("Alice", 25)
        person_dict = {"name": "Bob", "age": 30, "city": "Paris"}
        
        # result1 = greet(*person_tuple)
        # result2 = greet(**person_dict)
        
        pass
    
    # 练习3.3: 可变参数函数
    def create_flexible_function():
        """创建支持灵活参数的函数"""
        # TODO: 实现一个灵活的数据处理函数
        def process_data(*args, **kwargs):
            """处理任意数量的位置参数和关键字参数"""
            # 处理位置参数
            # 处理关键字参数
            # 返回处理结果
            pass
        
        return process_data
    
    # 练习3.4: 仅限位置参数和仅限关键字参数
    def position_keyword_only_params():
        """演示仅限位置参数(/)和仅限关键字参数(*)"""
        # TODO: 实现使用/和*的函数
        def advanced_function(pos_only, /, pos_or_kw, *, kw_only):
            """演示参数类型限制"""
            return f"pos_only={pos_only}, pos_or_kw={pos_or_kw}, kw_only={kw_only}"
        
        # 测试不同的调用方式
        try:
            # 正确调用
            result1 = advanced_function(1, 2, kw_only=3)
            result2 = advanced_function(1, pos_or_kw=2, kw_only=3)
            
            # 错误调用(应该抛出异常)
            # result3 = advanced_function(pos_only=1, pos_or_kw=2, kw_only=3)
            # result4 = advanced_function(1, 2, 3)
            
            return [result1, result2]
        except TypeError as e:
            return f"参数错误: {e}"
    
    # 演示解包操作
    print("3. 解包操作的高级应用:")
    
    try:
        multiple_assignment()
        function_argument_unpacking()
        process_func = create_flexible_function()
        param_results = position_keyword_only_params()
        
        print(f"参数限制测试: {param_results}")
    except Exception as e:
        print(f"解包操作练习出错: {e}")


@dataclass
class Person:
    """练习4: 数据类的高级用法"""
    name: str
    age: int
    email: Optional[str] = None
    tags: List[str] = field(default_factory=list)
    metadata: Dict[str, Any] = field(default_factory=dict)
    
    def __post_init__(self):
        """数据类初始化后处理"""
        # TODO: 实现初始化后的数据验证和处理
        pass
    
    @property
    def display_name(self) -> str:
        """显示名称"""
        # TODO: 实现显示名称逻辑
        pass
    
    def add_tag(self, tag: str) -> None:
        """添加标签"""
        # TODO: 实现标签添加逻辑
        pass


def dataclass_exercises():
    """
    练习4: 数据类(dataclass)的高级应用
    """
    print("\n=== 数据类练习 ===")
    
    # TODO: 创建和使用数据类实例
    # 1. 基本创建
    # 2. 字段默认值
    # 3. 后处理方法
    # 4. 比较和哈希
    
    try:
        person = Person("Alice", 30, "alice@example.com")
        print(f"创建的人员: {person}")
        
        # 测试各种功能
        person.add_tag("developer")
        print(f"添加标签后: {person}")
        print(f"显示名称: {person.display_name}")
    except Exception as e:
        print(f"数据类练习出错: {e}")


def pattern_matching_exercises():
    """
    练习5: 模式匹配(match-case) - Python 3.10+
    
    注意: 这个功能需要Python 3.10或更高版本
    """
    print("\n=== 模式匹配练习 ===")
    
    if sys.version_info < (3, 10):
        print("模式匹配需要Python 3.10+，当前版本不支持")
        return
    
    # TODO: 实现模式匹配示例
    def process_data_with_match(data):
        """使用模式匹配处理不同类型的数据"""
        # match data:
        #     case int() if data > 0:
        #         return f"正整数: {data}"
        #     case int() if data < 0:
        #         return f"负整数: {data}"
        #     case 0:
        #         return "零"
        #     case str() if len(data) > 0:
        #         return f"非空字符串: {data}"
        #     case []:
        #         return "空列表"
        #     case [x] if isinstance(x, int):
        #         return f"单元素整数列表: {x}"
        #     case [x, y]:
        #         return f"双元素列表: {x}, {y}"
        #     case {'name': name, 'age': age}:
        #         return f"人员信息: {name}, {age}岁"
        #     case _:
        #         return f"未知类型: {type(data)}"
        pass
    
    # 测试模式匹配
    test_cases = [
        42, -10, 0, "hello", [], [1], [1, 2], {'name': 'Alice', 'age': 30}, None
    ]
    
    try:
        for case in test_cases:
            result = process_data_with_match(case)
            print(f"输入: {case} -> 输出: {result}")
    except Exception as e:
        print(f"模式匹配练习出错: {e}")


def type_annotation_exercises():
    """
    练习6: 类型注解和泛型的高级用法
    """
    print("\n=== 类型注解练习 ===")
    
    # 练习6.1: 泛型类型
    T = TypeVar('T')
    
    class Stack(Generic[T]):
        """泛型栈实现"""
        def __init__(self) -> None:
            self._items: List[T] = []
        
        def push(self, item: T) -> None:
            """入栈"""
            # TODO: 实现入栈操作
            pass
        
        def pop(self) -> Optional[T]:
            """出栈"""
            # TODO: 实现出栈操作
            pass
        
        def peek(self) -> Optional[T]:
            """查看栈顶"""
            # TODO: 实现查看栈顶操作
            pass
        
        def is_empty(self) -> bool:
            """检查是否为空"""
            # TODO: 实现空栈检查
            pass
    
    # 练习6.2: 复杂类型注解
    def process_user_data(
        users: List[Dict[str, Union[str, int]]],
        filters: Optional[Dict[str, Any]] = None
    ) -> Tuple[List[Dict[str, Any]], int]:
        """处理用户数据"""
        # TODO: 实现用户数据处理
        # 返回过滤后的用户列表和总数
        pass
    
    # 演示类型注解
    try:
        # 创建泛型栈
        int_stack: Stack[int] = Stack()
        str_stack: Stack[str] = Stack()
        
        # 测试栈操作
        int_stack.push(1)
        int_stack.push(2)
        str_stack.push("hello")
        str_stack.push("world")
        
        print(f"整数栈顶: {int_stack.peek()}")
        print(f"字符串栈顶: {str_stack.peek()}")
        
        # 测试用户数据处理
        users = [
            {'name': 'Alice', 'age': 30},
            {'name': 'Bob', 'age': 25},
            {'name': 'Charlie', 'age': 35}
        ]
        result, count = process_user_data(users, {'min_age': 30})
        print(f"处理结果: {result}, 总数: {count}")
    except Exception as e:
        print(f"类型注解练习出错: {e}")


def demonstrate_syntax_sugar():
    """
    演示所有语法糖功能
    """
    print("=== Python语法糖综合演示 ===")
    
    # 执行各个练习
    walrus_operator_exercises()
    advanced_fstring_exercises()
    unpacking_exercises()
    dataclass_exercises()
    pattern_matching_exercises()
    type_annotation_exercises()
    
    print("\n=== 语法糖练习完成 ===")


if __name__ == "__main__":
    demonstrate_syntax_sugar()
